﻿using NDF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace NDF
{
    /// <summary>
    /// 提供一组针对枚举类型和枚举值的常用工具型操作方法。
    /// </summary>
    public static class EnumHelper
    {
        /// <summary>
        /// 获取枚举值的字段显示名称。
        /// </summary>
        /// <param name="enumValue">枚举值。</param>
        /// <returns>枚举值的字段显示名称。</returns>
        public static string DisplayName(this System.Enum enumValue)
        {
            return System.Enum.GetName(enumValue.GetType(), enumValue);
        }

        /// <summary>
        /// 获取指定枚举类型 T 中定义的所有枚举字段的值所组成的一个数组。
        /// </summary>
        /// <typeparam name="T">表示一个枚举类型。</typeparam>
        /// <returns>返回指定枚举类型 T 中定义的所有枚举字段的值所组成的一个数组。</returns>
        public static T[] GetFields<T>()
        {
            Type enumType = typeof(T);
            if (enumType.IsAssignableFrom(typeof(Enum)))
            {
                throw new ArgumentException("指定的参数 enumType 不是一个枚举类型。", "enumType");
            }
            string[] names = Enum.GetNames(enumType);
            List<T> list = new List<T>();
            foreach (var name in names)
            {
                list.Add((T)Enum.Parse(enumType, name));
            }
            return list.ToArray();
        }

        /// <summary>
        /// 获取指定枚举类型 enumType 中定义的所有枚举字段的值所组成的一个数组。
        /// </summary>
        /// <param name="enumType">表示一个枚举类型。</param>
        /// <returns>返回指定枚举类型 enumType 中定义的所有枚举字段的值所组成的一个数组。</returns>
        public static object[] GetFields(Type enumType)
        {
            if (enumType.IsSubclassOf(typeof(Enum)))
            {
                throw new ArgumentException("指定的参数 enumType 不是一个枚举类型。", "enumType");
            }
            string[] names = Enum.GetNames(enumType);
            List<object> list = new List<object>();
            foreach (var name in names)
            {
                list.Add(Enum.Parse(enumType, name));
            }
            return list.ToArray();
        }


        /// <summary>
        /// 判断某个枚举类型是否定义了 <see cref="FlagsAttribute"/> 属性。
        /// </summary>
        /// <param name="enumType">要判断的枚举类型。</param>
        /// <returns>如果该枚举类型定义了 <see cref="FlagsAttribute"/> 属性，则返回 true，否则返回 false。</returns>
        public static bool IsFlagsDefined(Type enumType)
        {
            if (enumType.IsSubclassOf(typeof(Enum)))
            {
                throw new ArgumentException("指定的参数 enumType 不是一个枚举类型。", "enumType");
            }
            return enumType.GetCustomAttribute<FlagsAttribute>() == null;
        }

        /// <summary>
        /// 判断某个枚举值所属的枚举类型是否定义了 <see cref="FlagsAttribute"/> 属性。
        /// </summary>
        /// <param name="enumValue">要判断的类型的枚举值。</param>
        /// <returns>如果该枚举值所属的枚举类型定义了 <see cref="FlagsAttribute"/> 属性，则返回 true，否则返回 false。</returns>
        public static bool IsFlagsDefined(this Enum enumValue)
        {

            Type enumType = enumValue.GetType();
            return IsFlagsDefined(enumType);
        }



        /// <summary>
        /// 获取该枚举值字段所定义的所有自定义特性的数组。
        /// </summary>
        /// <param name="enumValue">要获取自定义特性的枚举值。</param>
        /// <returns>该枚举值字段所定义的所有自定义特性的数组。</returns>
        public static IEnumerable<Attribute> GetCustomeAttributes(this System.Enum enumValue)
        {
            return enumValue.GetType().GetField(enumValue.DisplayName()).GetCustomAttributes(true).OfType<Attribute>();
        }

        /// <summary>
        /// 获取该枚举值字段所定义的所有指定类型的自定义特性的数组。
        /// </summary>
        /// <param name="enumValue">要获取自定义特性的枚举值。<</param>
        /// <param name="attributeType">指定的自定义特性类型。</param>
        /// <returns>该枚举值字段所定义的所有指定类型的自定义特性的数组。</returns>
        public static IEnumerable<Attribute> GetCustomeAttributes(this System.Enum enumValue, System.Type attributeType)
        {
            return enumValue.GetType().GetField(enumValue.DisplayName()).GetCustomAttributes(attributeType, true).OfType<Attribute>();
        }

        /// <summary>
        /// 获取该枚举值字段所定义的所有指定类型的自定义特性的数组。
        /// </summary>
        /// <typeparam name="TResult">指定的自定义特性类型。</typeparam>
        /// <param name="enumValue">要获取自定义特性的枚举值。<</param>
        /// <returns>该枚举值字段所定义的所有指定类型的自定义特性的数组。</returns>
        public static IEnumerable<TResult> GetCustomeAttributes<TResult>(this System.Enum enumValue) where TResult : Attribute
        {
            return enumValue.GetType().GetField(enumValue.DisplayName()).GetCustomAttributes<TResult>(true);
        }
    }
}
